package com.geezdata.cps.base.aop;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import com.geezdata.cps.base.enums.ErrorCode;
import com.geezdata.cps.base.exceptions.MyException;
import com.geezdata.cps.base.request.BaseRequest;
import com.geezdata.cps.base.utils.ValidateUtil;
import com.google.common.collect.Lists;


@Aspect
@Order(3)
@Component
public class ValidateAspect {
	private static Logger logger = LoggerFactory.getLogger(ValidateAspect.class);
	
    @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public Object validate(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] arguments = joinPoint.getArgs();
        if (arguments != null) {
            for (Object argument : arguments) {
                if(null == argument)
                    continue;
                if (argument instanceof BindingResult) {
                    BindingResult bindingResult = (BindingResult) argument;
                    if (bindingResult.hasErrors()) {
                        List<String> errorMessages = Lists.newArrayList();
                        for (ObjectError objectError : bindingResult.getAllErrors()) {
                            errorMessages.add(objectError.getDefaultMessage());
                            if (objectError instanceof FieldError) {
                                errorMessages.add(((FieldError) objectError).getField()
                                        + objectError.getDefaultMessage());
                            } else {
                                errorMessages.add(objectError.getDefaultMessage());
                            }
                        }
                        logger.error("参数校验失败: {}", StringUtils.join(errorMessages, " & "));
                        throw new MyException(ErrorCode.INVALID_PARAMS.getCode(), "参数校验失败: "+StringUtils.join(errorMessages, " & "));
                    }
                }
                
                if (argument instanceof BaseRequest) {
                	Map<String, StringBuffer> errorMap = ValidateUtil.validate(argument);
                	if (errorMap != null && !errorMap.isEmpty()) {
	                	List<String> errorMessages = Lists.newArrayList();
	                	for (String key : errorMap.keySet()) {  
	                		StringBuffer value = errorMap.get(key);  
	                		errorMessages.add(value.toString());
	                	}  
	                	
	                	logger.error("参数校验失败: {}", StringUtils.join(errorMessages, " & "));
	                    throw new MyException(ErrorCode.INVALID_PARAMS.getCode(), "参数校验失败: "+StringUtils.join(errorMessages, " & "));
                	}
                }
            }
        }
        
        return joinPoint.proceed();
    }
}